import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.hutool.json.JSONConfig;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import cn.hutool.json.JSONUtil;
import com.meritdata.cloud.ai.client.entity.ClientReponse;
import com.meritdata.cloud.ai.client.entity.RestJsonRequest;
import com.meritdata.cloud.ai.client.entity.SyncResult;
import com.meritdata.cloud.ai.client.util.RSAUtil;

/**
* 同步服务访问客户端示例程序
*
* @author meritdata
*
*/
public class SyncHttpClient {

  // 证书key
  private static final String APP_KEY = "${token.key!''}";
  // 证书secret
  private static final String APP_SECRET = "${token.secret!''}";

  public static void main(String[] args) throws Exception {

	CloseableHttpClient client = HttpClients.createDefault();
	HttpPost httpPost = new HttpPost("${urlPrefix}/webapi/ai/model/sync/${service.id}");
	// 设置http的请求超时时间等配置
	RequestConfig requestConfig = RequestConfig.custom()
		.setConnectTimeout(10 * 1000)
		.setSocketTimeout(30 * 1000)
		.setConnectionRequestTimeout(10 * 1000)
		.build();
	httpPost.setConfig(requestConfig);
	// 设置执行请求的请求头
	httpPost.setHeader("App-Key", APP_KEY);
	httpPost.setHeader("App-Token", genToken(APP_SECRET));
	httpPost.setHeader("Content-type", "application/json");

	RestJsonRequest request = new RestJsonRequest();
	List<Map<String, Object>> list = new ArrayList<>();
	Map<String, Object> row = new HashMap<>();
	//TODO set row data for each column
	<#list columns as col>
	<#if col.type == 'DOUBLE'>
		row.put("${col.name}", 1);
	<#elseif col.type == 'DECIMAL'>
		row.put("${col.name}", 1);
	<#elseif col.type == 'LONG'>
		row.put("${col.name}", 1);
	<#elseif col.type == 'INT'>
		row.put("${col.name}", 1);
	<#elseif col.type == 'FLOAT'>
		row.put("${col.name}", 1);
	<#elseif col.type == 'TIMESTAMP'>
		// 设置日期时间类型为yyyy-MM-dd格式的字符类型
		row.put("${col.name}", "2018-01-01");
	<#elseif col.type == 'DATETIME'>
		// 设置日期时间类型为yyyy-MM-dd格式的字符类型
		row.put("${col.name}", "2018-01-01");
	<#else>
		row.put("${col.name}", "label");
	</#if>
	</#list>
	// could add many rows data
	list.add(row);
	request.setData(list);

	Map<String, String> flowParams = new HashMap<>();
	<#list serviceParams as param>
	<#if param.paramName != '' && param.paramType != 'datasource' && param.paramName != 'system.appId'>
	flowParams.put("${param.paramName}", "${param.paramValue}");
	</#if>
	</#list>
	request.setFlowParams(flowParams);
	StringEntity entity = new StringEntity(JSONUtil.toJsonStr(request), "UTF-8");
	entity.setContentEncoding("UTF-8");
	httpPost.setEntity(entity);

	HttpResponse response = null;
	try {
	  response = client.execute(httpPost);
	} catch (Exception e){
	  String msg = e.getMessage();
	  if (msg.contains("Read timed out")) {
	    throw new Exception("请求超时，请修改http的请求超时时间，" + e.getMessage(), e);
	  } else {
	    throw new Exception(e.getMessage(), e);
	  }
	}
	HttpEntity responseEntity = response.getEntity();
	String content = EntityUtils.toString(responseEntity, "UTF-8");
	ClientReponse<SyncResult> clientReponse = JSONUtil.toBean(content, ClientReponse.class);
	System.out.println(clientReponse);
	if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
		if(clientReponse.getSuccess()) {
			SyncResult sr = JSONUtil.toBean(toJsonStr(clientReponse.getData()), SyncResult.class);
			System.out.println("请求成功：" + sr);
		} else {
			System.out.println("请求失败：" + clientReponse.getStatus() + "," + clientReponse.getMessage());
		}
	} else {
		System.out.println("请求异常：" + response.getStatusLine().getStatusCode() + ", " + clientReponse.getMessage());
	}

	client.close();
  }

  /**
  * 加密token
  * @param secret
  * @return
  */
  public static String genToken(String secret) {
	return RSAUtil.encryptByPublicKey(secret + "-" + new Date().getTime(), RSAUtil.PUBLIC_KEY);
  }


	/**
	* Object转string
	* @param jsonObject
	* @return
	*/
	public static String toJsonStr(Object jsonObject){
	JSONConfig config = JSONConfig.create();
	config.setIgnoreNullValue(false);
	config.setTransientSupport(false);
	return JSONUtil.toJsonStr(jsonObject,config);
	}

}